#!/usr/bin/python
"""
    Copyright (C) 2010 Sebastiano Merlino

    This file is part of pystful.

    pystful is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    pystful is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pystful.  If not, see <http://www.gnu.org/licenses/>.

"""

__license__ = 'GPL http://www.gnu.org/licenses/gpl.txt'
__author__ = "Sebastiano Merlino <etr@pensieroartificiale.com>"
__version__ = '0.1'

__doc__ = """
Usage:\n
    -h,--help : Show this help

"""

from restful_lib import Connection
#from console import Console
import sys
import getopt
import getpass

def http_get(path, args = None, headers={}, username=None, password=None):
    proto_selector = path.find("://")+3
    proto = ""
    if proto_selector != -1:
        proto = path[:proto_selector]
        path = path[proto_selector:]
    slash_idx = path.find("/")
    if slash_idx != -1:
        basepath = path[:slash_idx]
        resource = path[slash_idx+1:]
    else:
        basepath = path
        resource = ""
    conn = Connection("http://"+basepath, username, password)
    return conn.request(resource, "get", args, headers=headers)
        
def http_delete(path, args = None, headers={}, username=None, password=None):
    proto_selector = path.find("://")+3
    proto = ""
    if proto_selector != -1:
        proto = path[:proto_selector]
        path = path[proto_selector:]
    slash_idx = path.find("/")
    if slash_idx != -1:
        basepath = path[:slash_idx]
        resource = path[slash_idx+1:]
    else:
        basepath = path
        resource = ""
    conn = Connection("http://"+basepath, username, password)
    return conn.request(resource, "delete", args, headers=headers)
        
def http_head(path, args = None, headers={}, username=None, password=None):
    proto_selector = path.find("://")+3
    proto = ""
    if proto_selector != -1:
        proto = path[:proto_selector]
        path = path[proto_selector:]
    slash_idx = path.find("/")
    if slash_idx != -1:
        basepath = path[:slash_idx]
        resource = path[slash_idx+1:]
    else:
        basepath = path
        resource = ""
    conn = Connection("http://"+basepath, username, password)
    return conn.request(resource, "head", args, headers=headers)
    
def http_post(path, args = None, body = None, filename=None, headers={}, username=None, password=None):
    proto_selector = path.find("://")+3
    proto = ""
    if proto_selector != -1:
        proto = path[:proto_selector]
        path = path[proto_selector:]
    slash_idx = path.find("/")
    if slash_idx != -1:
        basepath = path[:slash_idx]
        resource = path[slash_idx+1:]
    else:
        basepath = path
        resource = ""
    conn = Connection("http://"+basepath, username, password)
    return conn.request(resource, "post", args , body = body, filename=filename, headers=headers)
    
def http_put(path, args = None, body = None, filename=None, headers={}, username=None, password=None):
    proto_selector = path.find("://")+3
    proto = ""
    if proto_selector != -1:
        proto = path[:proto_selector]
        path = path[proto_selector:]
    slash_idx = path.find("/")
    if slash_idx != -1:
        basepath = path[:slash_idx]
        resource = path[slash_idx+1:]
    else:
        basepath = path
        resource = ""
    conn = Connection("http://"+basepath, username, password)
    return conn.request(resource, "put", args , body = body, filename=filename, headers=headers)

opts_tranlation = {
        "--user" : "-u",
        "--password" : "-p",
        "--method" : "-m",
        "--resource" : "-r",
        "--args" : "-a",
        "--body" : "-b",
        "--filename" : "-f",
        "--headers" : "-l",
        "--console" : "-c"
}

def filter_opts(opt):
    if opt in opts_tranlation:
        return opts_tranlation[opt]
    else:
        return opt

def main():
    # parse command line options
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hu:pm:r:a:b:f:l:c", ["help","user=","password=","method=","resource=","args=","body=","filename=","headers=","console"])
    except getopt.error, msg:
        print msg
        print "for help use --help"
        sys.exit(2)
    opts_dict = {}
    # process options
    for o, a in opts:
        opts_dict[filter_opts(o)] = a
    if "-h" in opts_dict:
        print __doc__
        sys.exit(0)
#    elif "-c" in opts_dict:
#        console = Console()
#        console.main()
#        sys.exit(0)
    if "-m" not in opts_dict:
        print "Method is required"
        print __doc__
        sys.exit(0)
    if "-r" not in opts_dict:
        print "Resource is required"
        print __doc__
        sys.exit(0)
    method = opts_dict["-m"].upper()
    url = opts_dict["-r"]
    args = None
    headers = {}
    filename = None
    body = None
    if "-a" in opts_dict:
        args = opts_dict["-a"]
    if "-f" in opts_dict:
        filename = opts_dict["-f"]
    if "-b" in opts_dict:
        body = opts_dict["-b"]
    user = None
    password = None
    if "-p" in opts_dict:
        password = getpass.getpass()
    if "-u" in opts_dict:
        user = opts_dict["-u"]
    if "-l" in opts_dict:
        try:
            headers_list = opts_dict["-l"].strip().split(",")
            for header in headers_list:
                try:
                    head_name, head_value = header.strip().split(":")
                    headers[head_name] = head_value
                except:
                    print "\033[01;33mWARNING:\033[0m Errors in your headers"
        except: 
            print "\033[01;33mWARNING:\033[0m Errors in your headers"
    if method == "GET":
        print http_get(url, args, headers, user, password)
    elif method == "DELETE":
        print http_delete(url, args, headers, user, password)
    elif method == "HEAD":
        print http_head(url, args, headers, user, password)
    elif method == "POST":
        print http_post(url, args, body, filename, headers, user, password)
    elif method == "PUT":
        print http_put(url, args, body, filename, headers, user, password)
    else:
        print "\033[01;31mERROR:\033[0m Unknown method!"

if __name__ == "__main__":
    main()
